package com.demo.apparel.service.uniapp.Impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.demo.apparel.config.AppConfig;
import com.demo.apparel.config.WechatProperties;
import com.demo.apparel.dto.uniapp.WxLoginDTO;
import com.demo.apparel.dto.uniapp.WxPhoneLoginDTO;
import com.demo.apparel.dto.uniapp.WxUpdateDTO;
import com.demo.apparel.dto.uniapp.WxUserDTO;
import com.demo.apparel.entity.WxUser;
import com.demo.apparel.mapper.uniapp.WxUserMapper;
import com.demo.apparel.service.uniapp.WxUserService;
import com.demo.apparel.utils.JwtUtils;
import com.demo.apparel.utils.WechatUtils;
import com.demo.apparel.utils.WxPhoneUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Random;
import java.util.UUID;

@Service
public class WxUserServiceImpl implements WxUserService {

    @Autowired
    private WxUserMapper wxUserMapper;

    @Autowired
    private JwtUtils jwtUtils;

    @Autowired
    private WechatUtils wechatUtils;

    @Autowired
    private WechatProperties wechatProperties;

    @Autowired
    private AppConfig appConfig;
    //微信注册用户
    @Override
    public WxUserDTO login(WxLoginDTO loginDTO) {
        String code = loginDTO.getCode();
        // 通过 code 向微信服务器请求 openid
        String openid = wechatUtils.getOpenidByCode(code); // 你需要自己实现这个方法
        // 1. 查用户是否存在
        WxUser user = wxUserMapper.selectByOpenid(openid);
        if (user == null) {
            // 2. 不存在，注册新用户
            //生成随机的用户名+10位数字
            String username;
            Random random = new Random();
            WxUser existUser;

            // 循环直到生成不重复的用户名
            do {
                username = generateRandomUsername(10, random);
                existUser = wxUserMapper.selectByUsername(username);
            } while (existUser != null);  // 如果查到有重复就继续循环

            user = new WxUser();
            user.setId(UUID.randomUUID().toString().replace("-", ""));
            user.setOpenid(openid);
            user.setUsername(username);
            user.setPhone(loginDTO.getPhone());
//            https://i.imgtg.com/2023/01/16/QRqMK.jpg
//            https://picx.zhimg.com/80/v2-6afa72220d29f045c15217aa6b275808_720w.webp?source=1def8aca
            user.setAvatar("https://picx.zhimg.com/80/v2-6afa72220d29f045c15217aa6b275808_720w.webp?source=1def8aca");
            wxUserMapper.insertUser(user);
        }
        // 4. 生成 token
        String token = jwtUtils.createToken(user.getId(), user.getUsername());
        // 5. 构建返回 DTO
        WxUserDTO dto = new WxUserDTO();
        dto.setId(user.getId());
        dto.setOpenid(user.getOpenid());
        dto.setUsername(user.getUsername());
        dto.setAvatar(user.getAvatar());
        dto.setPhone(user.getPhone());
        dto.setEmail(user.getEmail());
        dto.setToken(token);
        return dto;
    }

    //返回随机数字的用户名方法
    private String generateRandomUsername(int length, Random random) {
        if (length < 6) {
            throw new IllegalArgumentException("用户名长度不能小于6，无法满足复杂度要求");
        }
        String lower = "abcdefghijklmnopqrstuvwxyz";
        String upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        String digits = "0123456789";
        String underscore = "_";
        String allChars = lower + upper + digits + underscore;
        StringBuilder sb = new StringBuilder();
        // 必须包含的字符
        sb.append(lower.charAt(random.nextInt(lower.length())));
        sb.append(upper.charAt(random.nextInt(upper.length())));
        sb.append(digits.charAt(random.nextInt(digits.length())));
        sb.append(digits.charAt(random.nextInt(digits.length())));
        sb.append(underscore.charAt(0)); // 只有一个 "_"
        // 剩余字符随机填充
        for (int i = sb.length(); i < length; i++) {
            sb.append(allChars.charAt(random.nextInt(allChars.length())));
        }
        // 打乱顺序
        char[] chars = sb.toString().toCharArray();
        for (int i = 0; i < chars.length; i++) {
            int j = random.nextInt(chars.length);
            char tmp = chars[i];
            chars[i] = chars[j];
            chars[j] = tmp;
        }
        return "微信用户" + new String(chars);
    }

    @Override
    public WxUserDTO updateUser(String userId, WxUpdateDTO updateDTO) {
        WxUser user = wxUserMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        // 把前端传过来的4个字段设置到user实体
        user.setUsername(updateDTO.getUsername());
        user.setPhone(updateDTO.getPhone());
//        user.setAvatar(updateDTO.getAvatar());
        user.setEmail(updateDTO.getEmail());

        // 🔍 调试打印，确认ID和值是否正确
        System.out.println("更新的ID：" + user.getId());
        System.out.println("更新的内容：" + user);

        int updateCount = wxUserMapper.updateUser(user);
        if (updateCount <= 0) {
            throw new RuntimeException("更新用户失败");
        }

        // 组装返回 DTO，保持token不变，token一般在controller生成或者保存在前端
        WxUserDTO dto = new WxUserDTO();
        dto.setId(user.getId());
        dto.setOpenid(user.getOpenid());
        dto.setUsername(user.getUsername());
        dto.setPhone(user.getPhone());
        dto.setAvatar(user.getAvatar());
        dto.setEmail(user.getEmail());
        dto.setToken(null);
        return dto;
    }

    //一键登录
    // 手机号登录（通过 code + encryptedData 解密）
    @Override
    public WxUserDTO loginWithPhone(WxPhoneLoginDTO dto) {
        // 1. 获取 session_key 和 openid
        String url = String.format(
                "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code",
                wechatProperties.getAppid(),
                wechatProperties.getSecret(),
                dto.getCode()
        );
        String response = HttpUtil.get(url);
        cn.hutool.json.JSONObject json = JSONUtil.parseObj(response);

        String sessionKey = json.getStr("session_key");
        String openid = json.getStr("openid");

        if (StrUtil.isBlank(sessionKey) || StrUtil.isBlank(openid)) {
            throw new RuntimeException("微信登录失败：" + json.toString());
        }

        // 2. 解密手机号
        String phone = WxPhoneUtils.decryptPhoneNumber(dto.getEncryptedData(), sessionKey, dto.getIv());
        if (StrUtil.isBlank(phone)) {
            throw new RuntimeException("手机号解密失败");
        }

        // 3. 数据库存储
        WxUser user = wxUserMapper.selectByOpenid(openid);
        if (user == null) {
            user = new WxUser();
            user.setId(IdUtil.simpleUUID());
            user.setOpenid(openid);
            user.setPhone(phone);
            user.setUsername("微信用户" + RandomUtil.randomString(6));
            user.setCreatedTime(LocalDateTime.now());
            user.setUpdatedTime(LocalDateTime.now());
            wxUserMapper.insertUser(user);
        } else {
            user.setPhone(phone);
            user.setUpdatedTime(LocalDateTime.now());
            wxUserMapper.updateUser(user);
        }

        // 4. 封装返回
        WxUserDTO dtoResult = new WxUserDTO();
        BeanUtil.copyProperties(user, dtoResult);
        dtoResult.setToken(jwtUtils.createToken(user.getId(), user.getUsername()));
        return dtoResult;
    }

    /**
     * 单独上传头像
     */

    @Override
    public String uploadAvatar(MultipartFile file, String userId) {
        if (file == null || file.isEmpty()) {
            throw new RuntimeException("上传文件为空");
        }

        String originalFilename = file.getOriginalFilename();
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        String filename = UUID.randomUUID() + suffix;

        // 本地保存路径
        String uploadDir = System.getProperty("user.dir") + "/avatar/";
        File dir = new File(uploadDir);
        if (!dir.exists()) {
            dir.mkdirs();
        }

        try {
            // 删除旧头像（如果有）
            WxUser user = wxUserMapper.selectById(userId);
            if (user != null && user.getAvatar() != null && user.getAvatar().startsWith("/static/avatar/")) {
                String oldFilename = user.getAvatar().replace("/static/avatar/", "");
                File oldFile = new File(uploadDir + oldFilename);
                if (oldFile.exists()) {
                    oldFile.delete(); // 删除旧头像
                }
            }

            // 保存新文件
            File dest = new File(uploadDir + filename);
            file.transferTo(dest);

            // 相对路径保存到数据库
            String relativeUrl = "/static/avatar/" + filename;
            wxUserMapper.updateAvatar(userId, relativeUrl);
            // 返回给前端完整路径

            return relativeUrl;

        } catch (IOException e) {
            throw new RuntimeException("上传失败：" + e.getMessage(), e);
        }
    }

    /**
     * 实现h5登录实现方法
     *
     */
    @Override
    public WxUserDTO registerH5(String phone, String password) {
        // 1. 查是否已存在该手机号
        WxUser existUser = wxUserMapper.selectByPhone(phone);
        if (existUser != null) {
            throw new RuntimeException("该手机号已注册，请直接登录");
        }
        // 2. 创建新用户
        WxUser user = new WxUser();
        user.setId(UUID.randomUUID().toString().replace("-", ""));
        user.setUsername(user.getUsername()); // 用户名直接用手机号
        user.setPhone(phone);
        user.setPassword(password); // 明文存储（你要求不加密）
        user.setAvatar("https://picx.zhimg.com/80/v2-6afa72220d29f045c15217aa6b275808_720w.webp?source=1def8aca");
        wxUserMapper.insertUser(user);

        return buildUserDTO(user);
    }

    /**
     * h5登录服务
     * @param phone
     * @param password
     * @return
     */
    @Override
    public WxUserDTO loginH5(String phone, String password) {
        WxUser user = wxUserMapper.selectByPhoneOrUsername(phone);
        if (user == null) {
            throw new RuntimeException("用户不存在，请先注册");
        }
        if (!password.equals(user.getPassword())) {
            throw new RuntimeException("密码错误");
        }
        return buildUserDTO(user);
    }

    /**
     * 构建返回 DTO
     */
    private WxUserDTO buildUserDTO(WxUser user) {
        String token = jwtUtils.createToken(user.getId(), user.getUsername());
        WxUserDTO dto = new WxUserDTO();
        dto.setId(user.getId());
        dto.setUsername(user.getUsername());
        dto.setPhone(user.getPhone());
        dto.setAvatar(user.getAvatar());
        dto.setToken(token);
        return dto;
    }

}

